/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef KEELS_NATIVE_ANIMATE_H
#define KEELS_NATIVE_ANIMATE_H

#include <cstdint>

#include "native_type.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Defines the expected frame rate range of the animation.
 *
 * @since 12
 */
typedef struct {
    /** Expected minimum frame rate. */
    uint32_t min;
    /** Expected maximum frame rate. */
    uint32_t max;
    /** Expected optimal frame rate. */
    uint32_t expected;
} Keels_ArkUI_ExpectedFrameRateRange;

/**
 * @brief Defines the callback type for when the animation playback is complete.
 *
 * @since 12
 */
typedef struct {
    /** Type of the <b>onFinish</b> callback. */
    Keels_ArkUI_FinishCallbackType type;
    /** Callback invoked when the animation playback is complete. */
    void (*callback)(void* userData);
    /** Custom type. */
    void* userData;
} Keels_ArkUI_AnimateCompleteCallback;

/**
 * @brief Defines the animation configuration.
 *
 * @since 12
 */
typedef struct Keels_ArkUI_AnimateOption Keels_ArkUI_AnimateOption;

typedef struct Keels_ArkUI_Curve Keels_ArkUI_Curve;
typedef struct Keels_ArkUI_Curve* Keels_ArkUI_CurveHandle;

typedef struct Keels_ArkUI_KeyframeAnimateOption Keels_ArkUI_KeyframeAnimateOption;
typedef struct Keels_ArkUI_AnimatorOption Keels_ArkUI_AnimatorOption;
typedef struct Keels_ArkUI_Animator* Keels_ArkUI_AnimatorHandle;

typedef struct Keels_ArkUI_AnimatorEvent Keels_ArkUI_AnimatorEvent;
typedef struct Keels_ArkUI_AnimatorOnFrameEvent Keels_ArkUI_AnimatorOnFrameEvent;

typedef struct Keels_ArkUI_TransitionEffect Keels_ArkUI_TransitionEffect;

/**
 * @brief Implements the native animation APIs provided by ArkUI.
 *
 * @version 1
 * @since 12
 */
typedef struct {
    /**
     * @brief Defines an explicit animation.
     *
     * @note Make sure the component attributes to be set in the event closure have been set before.
     *
     * @param context UIContext。
     * @param option Indicates the pointer to an animation configuration.
     * @param update Indicates the animation closure. The system automatically inserts a transition animation
     * for the state change caused by the closure.
     * @param complete Indicates the callback to be invoked when the animation playback is complete.
     * @return Returns <b>0</b> if the operation is successful; returns <b>401</b> if a parameter error occurs.
     */
    int32_t (*animateTo)(Keels_ArkUI_ContextHandle context, Keels_ArkUI_AnimateOption* option, Keels_ArkUI_ContextCallback* update,
        Keels_ArkUI_AnimateCompleteCallback* complete);

    int32_t (*keyframeAnimateTo)(Keels_ArkUI_ContextHandle context, Keels_ArkUI_KeyframeAnimateOption* option);
    Keels_ArkUI_AnimatorHandle (*createAnimator)(Keels_ArkUI_ContextHandle context, Keels_ArkUI_AnimatorOption* option);
    void (*disposeAnimator)(Keels_ArkUI_AnimatorHandle animator);
} Keels_ArkUI_NativeAnimateAPI_1;

/**
 * @brief Creates an animation configuration.
 *
 * @return Returns the pointer to the created animation configuration.
 * @since 12
 */
Keels_ArkUI_AnimateOption* Keels_ArkUI_AnimateOption_Create(void);

/**
 * @brief Destroys an animation configuration.
 *
 * @since 12
 */
void Keels_ArkUI_AnimateOption_Dispose(Keels_ArkUI_AnimateOption* option);

/**
 * @brief Obtains the animation duration, in milliseconds.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @return Returns the duration.
 * @since 12
 */
uint32_t Keels_ArkUI_AnimateOption_GetDuration(Keels_ArkUI_AnimateOption* option);

/**
 * @brief Obtains the animation playback speed.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @return Returns the animation playback speed.
 * @since 12
 */
float Keels_ArkUI_AnimateOption_GetTempo(Keels_ArkUI_AnimateOption* option);

/**
 * @brief Obtains the animation curve.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @return Returns the animated curve.
 * @since 12
 */
Keels_ArkUI_AnimationCurve Keels_ArkUI_AnimateOption_GetCurve(Keels_ArkUI_AnimateOption* option);

/**
 * @brief Obtains the animation delay, in milliseconds.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @return Returns the animation delay.
 * @since 12
 */
int32_t Keels_ArkUI_AnimateOption_GetDelay(Keels_ArkUI_AnimateOption* option);

/**
 * @brief Obtains the number of times that an animation is played.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @return Returns the number of times that the animation is played.
 * @since 12
 */
int32_t Keels_ArkUI_AnimateOption_GetIterations(Keels_ArkUI_AnimateOption* option);

/**
 * @brief Obtains the animation playback mode.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @return Returns the animation playback mode.
 * @since 12
 */
Keels_ArkUI_AnimationPlayMode Keels_ArkUI_AnimateOption_GetPlayMode(Keels_ArkUI_AnimateOption* option);

/**
 * @brief Obtains the expected frame rate range of an animation.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @return Returns the expected frame rate range.
 * @since 12
 */
Keels_ArkUI_ExpectedFrameRateRange* Keels_ArkUI_AnimateOption_GetExpectedFrameRateRange(Keels_ArkUI_AnimateOption* option);

/**
 * @brief Sets the animation duration.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @param value Indicates the duration, in milliseconds.
 * @since 12
 */
void Keels_ArkUI_AnimateOption_SetDuration(Keels_ArkUI_AnimateOption* option, int32_t value);

/**
 * @brief Sets the animation playback speed.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @param value Indicates the animation playback speed.
 * @since 12
 */
void Keels_ArkUI_AnimateOption_SetTempo(Keels_ArkUI_AnimateOption* option, float value);

/**
 * @brief Sets the animation curve.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @param value Indicates the animated curve.
 * @since 12
 */
void Keels_ArkUI_AnimateOption_SetCurve(Keels_ArkUI_AnimateOption* option, Keels_ArkUI_AnimationCurve value);

/**
 * @brief Sets the animation delay.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @param value Indicates the animation delay.
 * @since 12
 */
void Keels_ArkUI_AnimateOption_SetDelay(Keels_ArkUI_AnimateOption* option, int32_t value);

/**
 * @brief Sets the number of times that an animation is played.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @param value Indicates the number of times that the animation is played.
 * @since 12
 */
void Keels_ArkUI_AnimateOption_SetIterations(Keels_ArkUI_AnimateOption* option, int32_t value);

/**
 * @brief Sets the animation playback mode.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @param value Indicates the animation playback mode.
 * @since 12
 */
void Keels_ArkUI_AnimateOption_SetPlayMode(Keels_ArkUI_AnimateOption* option, Keels_ArkUI_AnimationPlayMode value);

/**
 * @brief Sets the expected frame rate range of an animation.
 *
 * @param option Indicates the pointer to an animation configuration.
 * @param value Indicates the expected frame rate range.
 * @since 12
 */
void Keels_ArkUI_AnimateOption_SetExpectedFrameRateRange(Keels_ArkUI_AnimateOption* option, Keels_ArkUI_ExpectedFrameRateRange* value);

void Keels_ArkUI_AnimateOption_SetICurve(Keels_ArkUI_AnimateOption* option, Keels_ArkUI_CurveHandle value);
Keels_ArkUI_CurveHandle Keels_ArkUI_AnimateOption_GetICurve(Keels_ArkUI_AnimateOption* option);

Keels_ArkUI_KeyframeAnimateOption* Keels_ArkUI_KeyframeAnimateOption_Create(int32_t size);
void Keels_ArkUI_KeyframeAnimateOption_Dispose(Keels_ArkUI_KeyframeAnimateOption* option);
int32_t Keels_ArkUI_KeyframeAnimateOption_SetDelay(Keels_ArkUI_KeyframeAnimateOption* option, int32_t value);
int32_t Keels_ArkUI_KeyframeAnimateOption_SetIterations(Keels_ArkUI_KeyframeAnimateOption* option, int32_t value);
int32_t Keels_ArkUI_KeyframeAnimateOption_RegisterOnFinishCallback(
    Keels_ArkUI_KeyframeAnimateOption* option, void* userData, void (*onFinish)(void* userData));
int32_t Keels_ArkUI_KeyframeAnimateOption_SetDuration(Keels_ArkUI_KeyframeAnimateOption* option, int32_t value, int32_t index);
int32_t Keels_ArkUI_KeyframeAnimateOption_SetCurve(
    Keels_ArkUI_KeyframeAnimateOption* option, Keels_ArkUI_CurveHandle value, int32_t index);
int32_t Keels_ArkUI_KeyframeAnimateOption_RegisterOnEventCallback(
    Keels_ArkUI_KeyframeAnimateOption* option, void* userData, void (*event)(void* userData), int32_t index);
int32_t Keels_ArkUI_KeyframeAnimateOption_GetDelay(Keels_ArkUI_KeyframeAnimateOption* option);
int32_t Keels_ArkUI_KeyframeAnimateOption_GetIterations(Keels_ArkUI_KeyframeAnimateOption* option);
int32_t Keels_ArkUI_KeyframeAnimateOption_GetDuration(Keels_ArkUI_KeyframeAnimateOption* option, int32_t index);
Keels_ArkUI_CurveHandle Keels_ArkUI_KeyframeAnimateOption_GetCurve(Keels_ArkUI_KeyframeAnimateOption* option, int32_t index);
Keels_ArkUI_AnimatorOption* Keels_ArkUI_AnimatorOption_Create(int32_t keyframeSize);
void Keels_ArkUI_AnimatorOption_Dispose(Keels_ArkUI_AnimatorOption* option);
int32_t Keels_ArkUI_AnimatorOption_SetDuration(Keels_ArkUI_AnimatorOption* option, int32_t value);
int32_t Keels_ArkUI_AnimatorOption_SetDelay(Keels_ArkUI_AnimatorOption* option, int32_t value);
int32_t Keels_ArkUI_AnimatorOption_SetIterations(Keels_ArkUI_AnimatorOption* option, int32_t value);
int32_t Keels_ArkUI_AnimatorOption_SetFill(Keels_ArkUI_AnimatorOption* option, Keels_ArkUI_AnimationFillMode value);
int32_t Keels_ArkUI_AnimatorOption_SetDirection(Keels_ArkUI_AnimatorOption* option, Keels_ArkUI_AnimationDirection value);
int32_t Keels_ArkUI_AnimatorOption_SetCurve(Keels_ArkUI_AnimatorOption* option, Keels_ArkUI_CurveHandle value);
int32_t Keels_ArkUI_AnimatorOption_SetBegin(Keels_ArkUI_AnimatorOption* option, float value);
int32_t Keels_ArkUI_AnimatorOption_SetEnd(Keels_ArkUI_AnimatorOption* option, float value);
int32_t Keels_ArkUI_AnimatorOption_SetExpectedFrameRateRange(
    Keels_ArkUI_AnimatorOption* option, Keels_ArkUI_ExpectedFrameRateRange* value);
int32_t Keels_ArkUI_AnimatorOption_SetKeyframe(Keels_ArkUI_AnimatorOption* option, float time, float value, int32_t index);
int32_t Keels_ArkUI_AnimatorOption_SetKeyframeCurve(Keels_ArkUI_AnimatorOption* option, Keels_ArkUI_CurveHandle value, int32_t index);
int32_t Keels_ArkUI_AnimatorOption_GetDuration(Keels_ArkUI_AnimatorOption* option);
int32_t Keels_ArkUI_AnimatorOption_GetDelay(Keels_ArkUI_AnimatorOption* option);
int32_t Keels_ArkUI_AnimatorOption_GetIterations(Keels_ArkUI_AnimatorOption* option);
Keels_ArkUI_AnimationFillMode Keels_ArkUI_AnimatorOption_GetFill(Keels_ArkUI_AnimatorOption* option);
Keels_ArkUI_AnimationDirection Keels_ArkUI_AnimatorOption_GetDirection(Keels_ArkUI_AnimatorOption* option);
Keels_ArkUI_CurveHandle Keels_ArkUI_AnimatorOption_GetCurve(Keels_ArkUI_AnimatorOption* option);
float Keels_ArkUI_AnimatorOption_GetBegin(Keels_ArkUI_AnimatorOption* option);
float Keels_ArkUI_AnimatorOption_GetEnd(Keels_ArkUI_AnimatorOption* option);
Keels_ArkUI_ExpectedFrameRateRange* Keels_ArkUI_AnimatorOption_GetExpectedFrameRateRange(Keels_ArkUI_AnimatorOption* option);
float Keels_ArkUI_AnimatorOption_GetKeyframeTime(Keels_ArkUI_AnimatorOption* option, int32_t index);
float Keels_ArkUI_AnimatorOption_GetKeyframeValue(Keels_ArkUI_AnimatorOption* option, int32_t index);
Keels_ArkUI_CurveHandle Keels_ArkUI_AnimatorOption_GetKeyframeCurve(Keels_ArkUI_AnimatorOption* option, int32_t index);
void* Keels_ArkUI_AnimatorEvent_GetUserData(Keels_ArkUI_AnimatorEvent* event);
void* Keels_ArkUI_AnimatorOnFrameEvent_GetUserData(Keels_ArkUI_AnimatorOnFrameEvent* event);
float Keels_ArkUI_AnimatorOnFrameEvent_GetValue(Keels_ArkUI_AnimatorOnFrameEvent* event);
int32_t Keels_ArkUI_AnimatorOption_RegisterOnFrameCallback(
    Keels_ArkUI_AnimatorOption* option, void* userData, void (*callback)(Keels_ArkUI_AnimatorOnFrameEvent* event));
int32_t Keels_ArkUI_AnimatorOption_RegisterOnFinishCallback(
    Keels_ArkUI_AnimatorOption* option, void* userData, void (*callback)(Keels_ArkUI_AnimatorEvent* event));
int32_t Keels_ArkUI_AnimatorOption_RegisterOnCancelCallback(
    Keels_ArkUI_AnimatorOption* option, void* userData, void (*callback)(Keels_ArkUI_AnimatorEvent* event));
int32_t Keels_ArkUI_AnimatorOption_RegisterOnRepeatCallback(
    Keels_ArkUI_AnimatorOption* option, void* userData, void (*callback)(Keels_ArkUI_AnimatorEvent* event));
int32_t Keels_ArkUI_Animator_ResetAnimatorOption(Keels_ArkUI_AnimatorHandle animator, Keels_ArkUI_AnimatorOption* option);
int32_t Keels_ArkUI_Animator_Play(Keels_ArkUI_AnimatorHandle animator);
int32_t Keels_ArkUI_Animator_Finish(Keels_ArkUI_AnimatorHandle animator);
int32_t Keels_ArkUI_Animator_Pause(Keels_ArkUI_AnimatorHandle animator);
int32_t Keels_ArkUI_Animator_Cancel(Keels_ArkUI_AnimatorHandle animator);
int32_t Keels_ArkUI_Animator_Reverse(Keels_ArkUI_AnimatorHandle animator);
Keels_ArkUI_CurveHandle Keels_ArkUI_Curve_CreateCurveByType(Keels_ArkUI_AnimationCurve curve);
Keels_ArkUI_CurveHandle Keels_ArkUI_Curve_CreateStepsCurve(int32_t count, bool end);
Keels_ArkUI_CurveHandle Keels_ArkUI_Curve_CreateCubicBezierCurve(float x1, float y1, float x2, float y2);
Keels_ArkUI_CurveHandle Keels_ArkUI_Curve_CreateSpringCurve(float velocity, float mass, float stiffness, float damping);
Keels_ArkUI_CurveHandle Keels_ArkUI_Curve_CreateSpringMotion(float response, float dampingFraction, float overlapDuration);
Keels_ArkUI_CurveHandle Keels_ArkUI_Curve_CreateResponsiveSpringMotion(
    float response, float dampingFraction, float overlapDuration);
Keels_ArkUI_CurveHandle Keels_ArkUI_Curve_CreateInterpolatingSpring(float velocity, float mass, float stiffness, float damping);
Keels_ArkUI_CurveHandle Keels_ArkUI_Curve_CreateCustomCurve(
    void* userData, float (*interpolate)(float fraction, void* userdata));
void Keels_ArkUI_Curve_DisposeCurve(Keels_ArkUI_CurveHandle curveHandle);

Keels_ArkUI_TransitionEffect* Keels_ArkUI_CreateOpacityTransitionEffect(float opacity);
Keels_ArkUI_TransitionEffect* Keels_ArkUI_CreateTranslationTransitionEffect(Keels_ArkUI_TranslationOptions* translate);
Keels_ArkUI_TransitionEffect* Keels_ArkUI_CreateScaleTransitionEffect(Keels_ArkUI_ScaleOptions* scale);
Keels_ArkUI_TransitionEffect* Keels_ArkUI_CreateRotationTransitionEffect(Keels_ArkUI_RotationOptions* rotate);
Keels_ArkUI_TransitionEffect* Keels_ArkUI_CreateMovementTransitionEffect(Keels_ArkUI_TransitionEdge move);
Keels_ArkUI_TransitionEffect* Keels_ArkUI_CreateAsymmetricTransitionEffect(
    Keels_ArkUI_TransitionEffect* appear, Keels_ArkUI_TransitionEffect* disappear);
void Keels_ArkUI_TransitionEffect_Dispose(Keels_ArkUI_TransitionEffect* effect);
int32_t Keels_ArkUI_TransitionEffect_Combine(Keels_ArkUI_TransitionEffect* effect, Keels_ArkUI_TransitionEffect* combine);
int32_t Keels_ArkUI_TransitionEffect_SetAnimation(Keels_ArkUI_TransitionEffect* effect, Keels_ArkUI_AnimateOption* animation);
#ifdef __cplusplus
};
#endif

#endif // KEELS_NATIVE_ANIMATE_H